package org.darcy.config.shiro.realm;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.darcy.entity.SysResources;
import org.darcy.entity.SysUser;
import org.darcy.framework.blog.business.enums.UserStatusEnum;
import org.darcy.framework.blog.business.enums.UserTypeEnum;
import org.darcy.model.SysRoleModel;
import org.darcy.service.SysResourcesService;
import org.darcy.service.SysRoleService;
import org.darcy.service.SysUserService;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * Shiro-密码输入错误的状态下重试次数的匹配管理
 *
 */
public class ShiroRealm extends AuthorizingRealm {

	@Resource
	private SysUserService userService;

	@Resource
	private SysResourcesService resourcesService;

	@Resource
	private SysRoleService roleService;

	/**
	 * 提供账户信息返回认证信息（用户的角色信息集合）
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 获取用户的输入的账号.
		String username = (String) token.getPrincipal();
		SysUser user = userService.getByUserName(username);
		if (user == null) {
			throw new UnknownAccountException("账号不存在！");
		}
		if (user.getStatus() != null && UserStatusEnum.DISABLE.getCode().equals(user.getStatus())) {
			throw new LockedAccountException("帐号已被锁定，禁止登录！");
		}
		return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(username), getName());
	}

	/**
	 * 权限认证，为当前登录的Subject授予角色和权限（角色的权限信息集合）
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		// 权限信息对象info,用来存放查出的用户的所有的角色（role）及权限（permission）
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
		if (null == user) {
			return info;
		}
		// 赋予角色
		List<SysRoleModel> roleList = roleService.listRolesByUserId(user.getId());
		if (null != roleList) {
			for (SysRoleModel role : roleList) {
				info.addRole(role.getName());
			}
		}
		// 赋予权限
		List<SysResources> resourcesList = null;

		// ROOT用户默认拥有所有权限
		if (UserTypeEnum.ROOT.toString().equalsIgnoreCase(user.getUserType())) {
			resourcesList = resourcesService.getList(null);
		} else {
			resourcesList = resourcesService.listByUserId(user.getId());
		}

		if (!CollectionUtils.isEmpty(resourcesList)) {
			Set<String> permissionSet = new HashSet<>();
			for (SysResources resources : resourcesList) {
				String permission = null;
				if (!StringUtils.isEmpty(permission = resources.getPermission())) {
					permissionSet.addAll(Arrays.asList(permission.trim().split(",")));
				}
			}
			info.setStringPermissions(permissionSet);
		}
		return info;
	}

}
